home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
mint
/
utils
/
stlogin4.lzh
/
WRITE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-02
|
3KB
|
134 lines
/* UNIX like write program. Kees Lemmens; Juli 1992
This programs can be used to communicate between two login sessions
on a multitasking ATARI ST (MINT).
It behaves just like the UNIX write utility.
Bugs/remarks:
- I don't know how to determine the ttyname, so at this moment I use a
variable TTYNAME defined by GETTY. If not found then ttyname will be
"console". LOGNAME will be "root" if this variable is not found.
- Some programs - like tcsh - send a signal TTOU when a foreign process
attempts to write to their tty. This causes the foreign process to be
suspended. To avoid this problem the write program has to ignore such
signals.
- Because I don't want to rely upon a UTMP file, you can also write to
devices instead of users by using the -l option.
Any questions or suggestions about this program can be send to:
lemmens@dv.twi.tudelft.nl
*/
#include <stdio.h>
#include <fcntl.h> /* O_WRONLY etc. */
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "ux_misc.h"
#include <utmp.h>
#include <signal.h>
void set_bell(void)
{ long stack=0;
char *conterm=(void *)0x484; /* CON attribs (bell, keyclick) */
if(Super((void *)1L)==0)
stack=Super((void *)0L); /* supervisor mode */
*conterm |= 4; /* set bell attribute */
if(stack) Super((void *)stack); /* back to user mode */
}
void fatal(char *txt)
{ fprintf(stderr,"WRITE: %s\n",txt);
exit(1);
}
void do_write(char *totty)
{ int ttyfp;
time_t sec;
char c,warning[250],fulltty[100];
char *name,*mytty,*endmsg="\r\n<EOT>\r\n";
set_bell();
time(&sec);
if((name = getenv("LOGNAME")) == NULL) name = "root";
if((mytty = getenv("TTYNAME")) == NULL) mytty = "console";
mk_devnm(fulltty,totty);
if((ttyfp=open(fulltty,O_WRONLY)) < 0)
fatal("Can't open tty");
sprintf(warning,"\7\r\n\tMessage from %s (%s) [ %.19s ] ...\r\n\7",
name,mytty,ctime(&sec));
write(ttyfp,warning,strlen(warning));
puts("\7Write your message (Ctrl-D to stop)\7");
while(read(1,&c,1),c != '\4' && c != '\32')
{ write(ttyfp,&c,1);
if(c=='\r')
{ write(ttyfp,"\n",1);
putchar('\n');
}
}
write(ttyfp,endmsg,strlen(endmsg));
close(ttyfp);
}
void usage(void)
{ puts("\nUsage: write [-l <line>] | [<user>]");
exit(1);
}
void name2tty(char *name,char *totty)
{ extern int utmp_fd;
int fl=0;
struct utmp *w;
setutent();
while((w=getutent()) != NULL && !fl)
{ if(!strncmp(w->ut_name,name,sizeof(w->ut_name)) &&
w->ut_type == USER_PROCESS)
{ if(Pkill(w->ut_pid,SIGNULL) == 0) /* process exists ? */
{ strncpy(totty,w->ut_line,sizeof(w->ut_line));
fl=1;
}
else
{ w->ut_type=DEAD_PROCESS;
setutent(); /* rewind and */
pututline(w); /* correct UTMP entry */
}
}
}
endutent();
if(!fl)
{ puts("User is not logged on");
exit(0);
}
}
void main(int argc,char *argv[])
{ char totty[100];
int lfl=0;
#ifdef MINT /* ignore signal [Attempted write to foreign tty] */
signal(SIGTTOU,SIG_IGN);
#endif
if(argc<2) usage();
while(--argc>0) /* parse options */
{ if(*argv[1]=='-')
{ switch(*(++argv[1]))
{ case 'l': lfl=1; break;
default : usage();
}
++argv;
}
}
if(lfl) strcpy(totty,argv[1]);
else name2tty(argv[1],totty);
do_write(totty);
}